package com.myblog.controller;


import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.myblog.common.lang.Result;
import com.myblog.entity.*;
import com.myblog.mapper.BlogMapper;
import com.myblog.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author From:星羽恒
 * @since 2021-11-24
 */
@RestController
@RequestMapping("/blog")
public class BlogController {
    @Autowired
    BlogService blogService;
    @Autowired
    UserService userService;
    @Autowired
    TypeService typeService;
    @Autowired
    TagService tagService;
    @Autowired
    BlogTagsService blogTagsService;
    @Autowired
    CommentService commentService;

    /* 分页获取博客列表试 */
    @GetMapping("/blogs")
    public Result list(@RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize){
        Page page = new Page(pageNum, pageSize);
        IPage pageData = blogService.page(page, new QueryWrapper<Blog>().orderByDesc("create_time"));

        // 拿到当前分页下的所有博客
        List<Blog> blogs = pageData.getRecords();

        // 根据博客对应的 user_id ，建立一个 userMap， 最后用 blog_id 对应 user_id 回传
        Map<Long, User> userMap = new HashMap<>();
        // 根据博客对应的 type_id ，建立一个 typeMap， 最后用 blog_id 对应 type_id 回传
        Map<Long, Type> typeMap = new HashMap<>();
        for(Blog tempBlog : blogs){
            Long userId = tempBlog.getUserId();
            if(!userMap.containsKey(userId)){
                User tempUser = userService.getById(userId);
                tempUser.toProtected();
                userMap.put(userId,tempUser);
            }
            Long typeId = tempBlog.getTypeId();
            if(!typeMap.containsKey(typeId)){
                Type tempType = typeService.getById(typeId);
                typeMap.put(typeId,tempType);
            }
        }


        /* 不仅需要返回分页信息，还要携带与这些文章相关联的用户对象，前端根据 blog_id - user_id ，获得对应值 */
        return Result.succ(MapUtil.builder()
                            .put("pageContent",pageData)
                            .put("userMap",userMap)
                            .put("typeMap",typeMap)
                            .map()
        );
    }

    /* 指定 id 返回博客对象 */
    @GetMapping("/{id}")
    public Result detail(@PathVariable(name = "id") Long id) {
        Blog blog = blogService.getById(id);
        Assert.notNull(blog, "该博客已被删除");
        return Result.succ(blog);
    }


    /*推荐博客 */
    @GetMapping("/recommend")
    public Result getRecommend(){
        //返回第一页的前 5 篇 （敷衍一下）
        Page page = new Page(1, 7);
        IPage pageData = blogService.page(page, new QueryWrapper<Blog>().eq("recommend",true).orderByDesc("create_time"));

        // 拿到当前分页下的所有博客
        List<Blog> blogs = pageData.getRecords();

        return Result.succ(blogs);
    }


    /* 按分类筛选博客 */
    @GetMapping("/selectType")
    public Result getSelectType(@RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize, @RequestParam("typeId") long typeId ){

        Page page = new Page(pageNum, pageSize);

        IPage pageData = blogService.page(page, new QueryWrapper<Blog>().orderByDesc("create_time").eq("type_id",typeId));

        // 拿到当前分页下的所有博客
        List<Blog> blogs = pageData.getRecords();

        // 根据博客对应的 user_id ，建立一个 userMap， 最后用 blog_id 对应 user_id 回传
        Map<Long, User> userMap = new HashMap<>();
        for(Blog tempBlog : blogs){
            Long userId = tempBlog.getUserId();
            if(!userMap.containsKey(userId)){
                User tempUser = userService.getById(userId);
                tempUser.toProtected();
                userMap.put(userId,tempUser);
            }
        }

        //放指定的类别返回即可
        Type type = typeService.getById(typeId);

        /* 不仅需要返回分页信息，还要携带与这些文章相关联的用户对象，前端根据 blog_id - user_id ，获得对应值 */
        return Result.succ(MapUtil.builder()
                .put("pageContent",pageData)
                .put("userMap",userMap)
                .put("selectType",type)
                .map()
        );
    }


    /* 按标签筛选博客 */
    @GetMapping("/selectTag")
    public Result getSelectTag(@RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize, @RequestParam("tagId") long tagId ){

        Page page = new Page(pageNum, pageSize);
        IPage pageData = blogTagsService.page(page, new QueryWrapper<BlogTags>().orderByAsc("blogs_id").eq("tags_id",tagId));

        List<BlogTags> btList = pageData.getRecords();

        // 拿到当前分页下的所有博客
        List<Blog> blogs = new ArrayList<>();
        for(BlogTags tempBT : btList){
            Blog tempBlog = blogService.getById(tempBT.getBlogsId());
            blogs.add(tempBlog);
        }

        // 根据博客对应的 user_id ，建立一个 userMap， 最后用 blog_id 对应 user_id 回传
        Map<Long, User> userMap = new HashMap<>();
        // 根据博客对应的 type_id ，建立一个 typeMap， 最后用 blog_id 对应 type_id 回传
        Map<Long, Type> typeMap = new HashMap<>();
        for(Blog tempBlog : blogs){
            Long userId = tempBlog.getUserId();
            if(!userMap.containsKey(userId)){
                User tempUser = userService.getById(userId);
                userMap.put(userId,tempUser);
            }
            Long typeId = tempBlog.getTypeId();
            if(!typeMap.containsKey(typeId)){
                Type tempType = typeService.getById(typeId);
                typeMap.put(typeId,tempType);
            }
        }

        //放指定的类别返回即可
        Tag tag = tagService.getById(tagId);

        /* 不仅需要返回分页信息，还要携带与这些文章相关联的用户对象，前端根据 blog_id - user_id ，获得对应值 */
        return Result.succ(MapUtil.builder()
                .put("pageContent",pageData)
                .put("blogs",blogs)
                .put("userMap",userMap)
                .put("typeMap",typeMap)
                .put("selectTag",tag)
                .map()
        );
    }


    @GetMapping("/details")
    public Result getBlogDetails(@RequestParam("id") long id){
        /*
            需要返回的信息：
            1、博文对象
            2、作者对象
            3、该博文下的评论对象
        */

        Blog blog = blogService.getById(id);
        //浏览数 + 1
        blog.setViews(blog.getViews()+1);
        blogService.saveOrUpdate(blog);

        List<Comment> comments = commentService.list(new QueryWrapper<Comment>().orderByDesc("create_time").eq("blog_id",blog.getId()));
        User user = userService.getById(blog.getUserId());
        user.toProtected();

        return Result.succ(MapUtil.builder()
                            .put("user",user)
                            .put("blog",blog)
                            .put("comments",comments)
                            .map());
    }

}
